/**
 * Copyright (c) 2021 Wei-Lun Hsu. All Rights Reserved.
 */
/** @file zb32l03x_hal_trng.h
 *
 * @author Wei-Lun Hsu
 * @version 0.1
 * @date 2021/09/27
 * @license
 * @description
 */

#ifndef __ZB32L03x_HAL_TRNG_H
#define __ZB32L03x_HAL_TRNG_H

#ifdef __cplusplus
extern "C" {
#endif

#include "zb32l03x_hal_def.h"

/** @addtogroup ZB32L03x_HAL_Driver
  * @{
  */

/** @addtogroup TRNG
  * @{
  */
//=============================================================================
//                  Constant Definition
//=============================================================================
/** @defgroup TRNG_Exported_Constants TRNG Exported Constants
  * @{
  */

/**
 *  TRNG state
 */
typedef enum
{
    HAL_TRNG_STATE_RESET     = 0x00U,  /*!< TRNG not yet initialized or disabled */
    HAL_TRNG_STATE_READY     = 0x01U,  /*!< TRNG initialized and ready for use   */
    HAL_TRNG_STATE_BUSY      = 0x02U,  /*!< TRNG internal process is ongoing     */
    HAL_TRNG_STATE_TIMEOUT   = 0x03U,  /*!< TRNG timeout state                   */
    HAL_TRNG_STATE_ERROR     = 0x04U   /*!< TRNG error state                     */

} HAL_TRNG_State_TypeDef;


/**
  * @}
  */ /* End of group TRNG_Exported_Constants */


//=============================================================================
//                  Structure Definition
//=============================================================================
/** @defgroup TRNG_Exported_Types TRNG Exported Types
  * @{
  */

typedef enum
{
    TRNG_CLK_DIV8               = TRNG_CR_CLK_DIV_DIV8,
    TRNG_CLK_DIV4               = TRNG_CR_CLK_DIV_DIV4,
    TRNG_CLK_DIV2               = TRNG_CR_CLK_DIV_DIV2,
    TRNG_CLK_DIV1               = TRNG_CR_CLK_DIV_DIV1
}HAL_TRNG_ClockDivTypeDef;

typedef struct
{
    HAL_TRNG_ClockDivTypeDef                ClockDiv;    /*!< TRNG clock div*/

    bool                                    IS_EnableCED;      /*!< slave address */
} TRNG_InitTypeDef;

typedef struct
{
    TRNG_TypeDef                    *Instance;  /*!< Register base address   */
    TRNG_InitTypeDef                Init;

    HAL_LockTypeDef                 Lock;       /*!< TRNG locking object      */

    __IO HAL_TRNG_State_TypeDef     State;
} HAL_TRNG_Handle_TypeDef;




/**
  * @}
  */ /* End of group TRNG_Exported_Types */

//=============================================================================
//                  Macro Definition
//=============================================================================
/** @defgroup TRNG_Exported_Macros TRNG Exported Macros
  * @{
  */

#define TRNG_TIMEOUT_VALUE     100U

/** @defgroup RNG_Exported_Constants_Group1 RNG Interrupt definition
  * @{
  */
#define TRNG_IT_DRDY  TRNG_SR_DRDY  /*!< Data Ready interrupt  */
#define TRNG_IT_CEI   TRNG_SR_CEIS  /*!< Clock error interrupt */
#define TRNG_IT_SEI   TRNG_SR_SEIS  /*!< Seed error interrupt  */
/**
  * @}
  */

/** @defgroup RNG_Exported_Constants_Group2 RNG Flag definition
  * @{
  */
#define TRNG_FLAG_DRDY   TRNG_SR_DRDY  /*!< Data ready                 */
#define TRNG_FLAG_CECS   TRNG_SR_CECS  /*!< Clock error current status */
#define TRNG_FLAG_SECS   TRNG_SR_SECS  /*!< Seed error current status  */
/**
  * @}
  */

/**
  * @brief  Enables the TRNG peripheral.
  * @param  __HANDLE__ TRNG Handle
  * @retval None
  */
#define __HAL_TRNG_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |=  TRNG_CR_TRNGEN)

/**
  * @brief  Disables the TRNG peripheral.
  * @param  __HANDLE__ TRNG Handle
  * @retval None
  */
#define __HAL_TRNG_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~TRNG_CR_TRNGEN)

/**
  * @brief  Check the selected TRNG flag status.
  * @param  __HANDLE__ TRNG Handle
  * @param  __FLAG__ TRNG flag
  *          This parameter can be one of the following values:
  *            @arg TRNG_FLAG_DRDY:  Data ready
  *            @arg TRNG_FLAG_CECS:  Clock error current status
  *            @arg TRNG_FLAG_SECS:  Seed error current status
  * @retval The new state of __FLAG__ (SET or RESET).
  */
#define __HAL_TRNG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))

/**
  * @brief  Clears the selected TRNG flag status.
  * @param  __HANDLE__ TRNG handle
  * @param  __FLAG__ TRNG flag to clear
  * @note   WARNING: This is a dummy macro for HAL code alignment,
  *         flags TRNG_FLAG_DRDY, TRNG_FLAG_CECS and TRNG_FLAG_SECS are read-only.
  * @retval None
  */
#define __HAL_TRNG_CLEAR_FLAG(__HANDLE__, __FLAG__)                      /* dummy  macro */

/**
  * @brief  Enables the TRNG interrupts.
  * @param  __HANDLE__ TRNG Handle
  * @retval None
  */
#define __HAL_TRNG_ENABLE_IT(__HANDLE__) ((__HANDLE__)->Instance->CR |=  TRNG_CR_TRNGIE)

/**
  * @brief  Disables the TRNG interrupts.
  * @param  __HANDLE__ TRNG Handle
  * @retval None
  */
#define __HAL_TRNG_DISABLE_IT(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~TRNG_CR_TRNGIE)

/**
  * @brief  Checks whether the specified TRNG interrupt has occurred or not.
  * @param  __HANDLE__ TRNG Handle
  * @param  __INTERRUPT__ specifies the TRNG interrupt status flag to check.
  *         This parameter can be one of the following values:
  *            @arg TRNG_IT_DRDY: Data ready interrupt
  *            @arg TRNG_IT_CEI: Clock error interrupt
  *            @arg TRNG_IT_SEI: Seed error interrupt
  * @retval The new state of __INTERRUPT__ (SET or RESET).
  */
#define __HAL_TRNG_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->SR & (__INTERRUPT__)) == (__INTERRUPT__))

/**
  * @brief  Clear the TRNG interrupt status flags.
  * @param  __HANDLE__ TRNG Handle
  * @param  __INTERRUPT__ specifies the TRNG interrupt status flag to clear.
  *          This parameter can be one of the following values:
  *            @arg TRNG_IT_CEI: Clock error interrupt
  *            @arg TRNG_IT_SEI: Seed error interrupt
  * @note   TRNG_IT_DRDY flag is read-only, reading TRNG_DR register automatically clears TRNG_IT_DRDY.
  * @retval None
  */
#define __HAL_TRNG_CLEAR_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->SR) = ~(__INTERRUPT__))

#define IS_TRNG_ALL_INSTANCE(__HANDLE__)     ((__HANDLE__) == TRNG)




/**
  * @}
  */ /* End of group TRNG_Exported_Macros */


//=============================================================================
//                  Public Function Definition
//=============================================================================
/** @addtogroup TRNG_Exported_Functions
  * @{
  */
void HAL_TRNG_MspInit(HAL_TRNG_Handle_TypeDef *hTrng);
void HAL_TRNG_MspDeInit(HAL_TRNG_Handle_TypeDef *hTrng);
void HAL_TRNG_ReadyDataCallback(HAL_TRNG_Handle_TypeDef *hTrng);
void HAL_TRNG_ErrorCallback(HAL_TRNG_Handle_TypeDef *hTrng);
HAL_StatusTypeDef HAL_TRNG_Init(HAL_TRNG_Handle_TypeDef *hTrng);
HAL_StatusTypeDef HAL_TRNG_DeInit(HAL_TRNG_Handle_TypeDef *hTrng);
HAL_StatusTypeDef HAL_TRNG_GenerateRandomNumber(HAL_TRNG_Handle_TypeDef *hTrng, uint32_t *random32bit);
HAL_StatusTypeDef HAL_TRNG_GenerateRandomNumber_IT(HAL_TRNG_Handle_TypeDef *hTrng);
uint32_t HAL_TRNG_GetRandomNumber(HAL_TRNG_Handle_TypeDef *hTrng);
uint32_t HAL_TRNG_GetRandomNumber_IT(HAL_TRNG_Handle_TypeDef *hTrng);
uint32_t HAL_TRNG_ReadLastRandomNumber(HAL_TRNG_Handle_TypeDef *hTrng);
void HAL_TRNG_IRQHandler(HAL_TRNG_Handle_TypeDef *hTrng);

/**
  * @}
  */ /* End of group TRNG_Exported_Functions */

/**
  * @}
  */ /* End of group TRNG */

/**
  * @}
  */ /* End of group ZB32L03x_HAL_Driver */


#ifdef __cplusplus
}
#endif

#endif
